#coding:utf-8
#code by foRK
#QQ:261496481
#扫描单个IP或IP段的单一端口工具

import sys
import socket
import thread
import time

socket.setdefaulttimeout(10)  #设置了全局默认超时时间

if len(sys.argv) < 2:
	print 'version 1.0'
	print '%s [scanIP] [PORT]' % sys.argv[0]
	print '%s 192.168.1.1 80' % sys.argv[0]
	print '%s 192.168.1.1-192.168.1.255 80' % sys.argv[0]
	sys.exit(1)
	
scanIP = sys.argv[1]
PORT = sys.argv[2]


def ip2num(ip):
	ip1 = [int(x) for x in ip.split('.')]
	return ip1[0]<<24 | ip1[1]<<16 | ip1[2]<<8 | ip1[3]

	
def num2ip(num):
	if num>=IPend:
		print u"IP to list ok!"
	return '%s.%s.%s.%s' % (  (num & 0xff000000) >> 24,
                              (num & 0x00ff0000) >> 16,
                              (num & 0x0000ff00) >> 8,
                              num & 0x000000ff  )
							  
def num2ip_one(num):
	return '%s.%s.%s.%s' % (  (num & 0xff000000) >> 24,
                              (num & 0x00ff0000) >> 16,
                              (num & 0x0000ff00) >> 8,
                              num & 0x000000ff  )
							  
def listip(ip1, ip2):
	global IPend #定义一个全局变量IPend
	IPend=ip2
	return [num2ip(num) for num in range(ip1,ip2+1) if num & 0xff] #num & 0xff去掉首尾.0的IP
	
	
def scan_port(ip, port):
	try:
		s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
		res = s.connect_ex((ip,port))
		if (res == 0):
			print ip,u":",port,u"port open"
		s.close()
	except:
		print u"port scan error"
		
if __name__=='__main__':
	if len(scanIP) < 16:
		list_ip = [] 
		list_ip.append(num2ip_one(ip2num(scanIP)))
		print u"need scan"+str(len(list_ip))+u"IP"
		t = time.time()
#		thread.start_new_thread(scan_port,(list_ip[0],int(PORT)))
#		time.sleep(0.003)
		scan_port(list_ip[0], int(PORT))
		print 'used time:%f' % (time.time()-t)
	else:
		ipp = scanIP.split('-')
		list_ip = listip(ip2num(ipp[0]),ip2num(ipp[1]))
		print u"need scan"+str(len(list_ip))+u"IP"
		I1 = 0 #得到list的第一个元素
		t = time.time()
		while I1 < len(list_ip):
			thread.start_new_thread(scan_port,(list_ip[I1],int(PORT)))
			I1 = I1 + 1
			time.sleep(0.03) #休眠时间socket
		print 'used time:%f' % (time.time()-t)
